package com.plian.system.service.pf.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.bean.pf.LeadershipPayRecordExcelBean;
import com.plian.system.cache.UserCache;
import com.plian.system.common.status.CheckStatus;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.entity.hr.staff.StaffFiles;
import com.plian.system.entity.pf.LeadershipPayRecord;
import com.plian.system.entity.pf.LeadershipPayRecordDeclare;
import com.plian.system.entity.pf.LeadershipPayRecordDetail;
import com.plian.system.entity.sys.ApprovalMessage;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.mapper.pf.LeadershipPayRecordMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.search.TokenSearch;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.hr.staff.IStaffFilesService;
import com.plian.system.service.pf.ILeadershipPayRecordDeclareService;
import com.plian.system.service.pf.ILeadershipPayRecordDetailService;
import com.plian.system.service.pf.ILeadershipPayRecordService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.message.IApprovalMessageService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.pf.LeadershipPayRecordVO;
import com.plian.system.vo.yth.YthResult;
import com.plian.system.wrapper.pf.LeadershipPayRecordWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.ApprovalMessageTypeConstant.GZW_TYPE;
import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;
import static com.plian.system.constant.sys.FormTypeConstant.PF_LEADER_SHIP_RECORD;

/**
 * @Description: TODO
 * @Author: Take-off
 * @Date: 2023/3/27 10:15 AM
 * @Param
 * @return
 * @Version: 1.0
 **/
@Slf4j
@Service
@AllArgsConstructor
public class LeadershipPayRecordServiceImpl extends BaseServiceImpl<LeadershipPayRecordMapper,LeadershipPayRecord> implements ILeadershipPayRecordService, BaseFlowService {

    private final ILeadershipPayRecordDetailService payRecordDetailService;

    private final ILeadershipPayRecordDeclareService payRecordDeclareService;

    private final FormWorkflowService formWorkflowService;

    private final IFormCodeService formCodeService;

    private final FileService fileService;

    private final IStaffFilesService staffFilesService;

    private final LeadershipPayRecordWrapper leadershipPayRecordWrapper;

    private final IOrgService orgService;

    private final ISysUserService userService;

    private IApprovalMessageService approvalMessageService;
    @Override
    public boolean saveOrUpdate(LeadershipPayRecord leadershipPayRecord) {
        boolean flag = false;
        if (!Optional.ofNullable(leadershipPayRecord.getStatus()).isPresent()){
            leadershipPayRecord.setStatus(FormStatusConstant.UNREVIEWED);
        }
        if (leadershipPayRecord.getStatus().equals(FormStatusConstant.REJECT)){
            leadershipPayRecord.setStatus(FormStatusConstant.UNREVIEWED);
        }
        if (!Optional.ofNullable(leadershipPayRecord.getId()).isPresent()) {
            flag = true;
            leadershipPayRecord.setCode(formCodeService.getCode(FormTypeConstant.PF_LEADER_SHIP_RECORD));
            leadershipPayRecord.setFormType(String.valueOf(FormTypeConstant.PF_LEADER_SHIP_RECORD));
        }
        boolean result = super.saveOrUpdate(leadershipPayRecord);
        if (flag){
            fileService.saveAll(String.valueOf(leadershipPayRecord.getId()), leadershipPayRecord.getDocList());
        }else {
            fileService.edit(String.valueOf(leadershipPayRecord.getId()), leadershipPayRecord.getDocList());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public boolean deleteLogic(List<Long> ids) {
        for (Long id : ids) {
            LeadershipPayRecord leadershipPayRecord = getById(id);
            if (leadershipPayRecord == null) {
                return false;
            } else if (leadershipPayRecord.getStatus() != null &&
                    (leadershipPayRecord.getStatus() != FormStatusConstant.STASH && leadershipPayRecord.getStatus() != FormStatusConstant.UNREVIEWED)) {
                return false;
            }
            formWorkflowService.deleteProcessInstance(String.valueOf(id));
        }

        boolean result = super.deleteLogic(ids);
        if (result){
            payRecordDetailService.deleteByParentId(ids);
            payRecordDeclareService.deleteByParentId(ids);
        }

        return result;
    }

    @Override
    public HashMap<String,Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW, null);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String,Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH,null);
    }

    @Override
    public Boolean reject(String id, int formState,String comment) {
        return handleStatus(Long.valueOf(id), formState, comment);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED, null);
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id          主键
     * @param updateStatus  更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus, String comment) {
        try {
            LeadershipPayRecord leadershipPayRecord = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH){
                leadershipPayRecord.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                leadershipPayRecord.setApprovedTime(now);
            }
            if (StringUtil.isNotBlank(leadershipPayRecord.getDataSource()) &&
                    StringUtil.isNotBlank(leadershipPayRecord.getDataSourceId())){
                if (updateStatus == FormStatusConstant.FINISH || updateStatus == FormStatusConstant.REJECT){
                    ApprovalMessage approvalMessage = new ApprovalMessage();
                    approvalMessage.setDataSourceId(leadershipPayRecord.getDataSourceId());
                    approvalMessage.setOpinion(comment);
                    approvalMessage.setIsApprove(updateStatus == FormStatusConstant.FINISH ? 2 : 1);
                    approvalMessage.setIsSend(1);
                    approvalMessage.setDataSourceType(GZW_TYPE);

                    if (leadershipPayRecord.getDataSource().equals(YthConstant.DATA_NINGBO)) {
                        approvalMessage.setDataSourceType(YthConstant.DATA_NINGBO);
                        approvalMessage.setFilingUserName(UserCache.userIdToName(TokenUtil.getTokenUserId()));
                        approvalMessage.setFormType(FormTypeConstant.PF_LEADER_SHIP_RECORD);
                    }
                    approvalMessageService.save(approvalMessage);
                }
            }
            leadershipPayRecord.setStatus(updateStatus);
            updateById(leadershipPayRecord);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<LeadershipPayRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LeadershipPayRecord::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<LeadershipPayRecord> leadershipPayRecords = list(queryWrapper);
        List<LeadershipPayRecordVO> leadershipPayRecordVOS = leadershipPayRecordWrapper.entityToVO(leadershipPayRecords);
        List<PageData> pageDataList = new ArrayList<>();
        try{
            if (CollectionUtil.isNotEmpty(leadershipPayRecordVOS)){
                for (LeadershipPayRecordVO vo : leadershipPayRecordVOS){
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getFillingUnitName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getFillingUnitId());
                    pd.put("formType", vo.getFormType());
                    pd.put("orgName", vo.getFillingUnitName());
                    pageDataList.add(pd);
                }
            }
            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(PF_LEADER_SHIP_RECORD);
    }

    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public boolean submit(LeadershipPayRecord leadershipPayRecord) {
        boolean result = saveOrUpdate(leadershipPayRecord);
        if (result){
            List<LeadershipPayRecordDetail> payRecordDetails = leadershipPayRecord.getLeadershipPayRecordDetails();
            if (CollectionUtil.isNotEmpty(payRecordDetails)){
                for (LeadershipPayRecordDetail payRecordDetail : payRecordDetails){
                    if (payRecordDetail.getId() != null &&
                            Optional.ofNullable(payRecordDetail.getIsDeleted()).isPresent() && payRecordDetail.getIsDeleted().intValue() == 1) {
                        payRecordDetailService.removeById(payRecordDetail.getId());
                    }else {
                        payRecordDetail.setBaseId(leadershipPayRecord.getId());
                        payRecordDetailService.saveOrUpdate(payRecordDetail);
                    }
                }
            }
            List<LeadershipPayRecordDeclare> payRecordDeclares = leadershipPayRecord.getLeadershipPayRecordDeclares();
            if (CollectionUtil.isNotEmpty(payRecordDeclares)){
                for (LeadershipPayRecordDeclare payRecordDeclare : payRecordDeclares){
                    if (payRecordDeclare.getId() != null &&
                            Optional.ofNullable(payRecordDeclare.getIsDeleted()).isPresent() && payRecordDeclare.getIsDeleted().intValue() == 1) {
                        payRecordDeclareService.removeById(payRecordDeclare.getId());
                    }else {
                        payRecordDeclare.setBaseId(leadershipPayRecord.getId());
                        payRecordDeclareService.saveOrUpdate(payRecordDeclare);
                    }
                }
                leadershipPayRecord.setIsDeclare(1);
                result = saveOrUpdate(leadershipPayRecord);
            }
        }
        return result;
    }

    @Override
    public LeadershipPayRecordVO getDetailObj(LeadershipPayRecord leadershipPayRecord) {
        LeadershipPayRecord detail = getOne(Condition.getQueryWrapper(leadershipPayRecord));
        LeadershipPayRecordVO leadershipPayRecordVO = leadershipPayRecordWrapper.entityToVO(detail);

        //子项
        List<LeadershipPayRecordDetail> details = payRecordDetailService.list(new LambdaQueryWrapper<LeadershipPayRecordDetail>().eq(LeadershipPayRecordDetail::getBaseId, leadershipPayRecordVO.getId()));
        leadershipPayRecordVO.setLeadershipPayRecordDetails(details);

        List<LeadershipPayRecordDeclare> recordDeclares = payRecordDeclareService.list(new LambdaQueryWrapper<LeadershipPayRecordDeclare>().eq(LeadershipPayRecordDeclare::getBaseId, leadershipPayRecordVO.getId()));
        leadershipPayRecordVO.setLeadershipPayRecordDeclares(recordDeclares);

        return leadershipPayRecordVO;
    }

    @Override
    public ListResult<LeadershipPayRecordVO> list(@RequestBody Query query) {
        List<SearchEntity> entityList = query.getSearch();
        if (query.getAscs()==null&&query.getDescs()==null){
            query.setDescs("create_time");
        }
        QueryWrapper<LeadershipPayRecord> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new LeadershipPayRecord()), entityList
        );
        TokenSearch<LeadershipPayRecord> tokenSearch = new TokenSearch<>();
		tokenSearch.addTokenQuery(queryWrapper, query);

        IPage<LeadershipPayRecord> pages =page(Condition.getPage(query), queryWrapper);
        List<LeadershipPayRecordVO> leadershipPayRecordVOS = leadershipPayRecordWrapper.entityToVO(pages.getRecords());
        ListResult<LeadershipPayRecordVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(leadershipPayRecordVOS);
        listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
        return listResult;
    }

    @Override
    public List<LeadershipPayRecordDetail> uploadFile(MultipartFile multipartFile){
        List<LeadershipPayRecordDetail> leadershipPayRecordDetails = new ArrayList<>();

        try {
            byte[] bytes = IOUtils.toByteArray(multipartFile.getInputStream());
            InputStream inputStream = new ByteArrayInputStream(bytes);
            List<Object> excelEntity = new ArrayList<>();
            EasyExcel.read(inputStream).build()
                    .read(EasyExcel.readSheet(0).headRowNumber(4).head(LeadershipPayRecordExcelBean.class)
                            .registerReadListener(new PageReadListener<>(list -> excelEntity.addAll(list))).build());
            ImportExcelUtil.filterEmpty(excelEntity);
            //公司下的员工
            List<StaffFiles> staffFiles = staffFilesService.list(new LambdaQueryWrapper<StaffFiles>().eq(StaffFiles::getCompanyNameId, TokenUtil.getTokenOrgId()));
            for (Object object : excelEntity) {
                LeadershipPayRecordExcelBean excelBean = (LeadershipPayRecordExcelBean) object;
                LeadershipPayRecordDetail payRecordDetail = excelBeanToEntity(excelBean, staffFiles);
                leadershipPayRecordDetails.add(payRecordDetail);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return leadershipPayRecordDetails;
    }

    /**
     * @Description: //TODO excelBean转entity
     * @Author: Take-off
     * @Date: 10:38 AM 2023/3/28
     * @Param: [excelBean, staffFiles]
     * @return: com.plian.system.entity.pf.LeadershipPayRecordDetail
     **/
    private LeadershipPayRecordDetail excelBeanToEntity(LeadershipPayRecordExcelBean excelBean, List<StaffFiles> staffFiles){
        LeadershipPayRecordDetail payRecordDetail = new LeadershipPayRecordDetail();
        payRecordDetail.setSerialNumber(excelBean.getSerialNumber());
        String staffName = excelBean.getStaffName();
        if (StringUtil.isNotBlank(staffName)){
            Optional<StaffFiles> first = staffFiles.stream().filter(m -> Optional.ofNullable(m.getStaffName()).isPresent() && staffName.equals(m.getStaffName())).findFirst();
            if (first.isPresent()){
                payRecordDetail.setStaffId(first.get().getId());
                payRecordDetail.setStaffName(staffName);
                payRecordDetail.setStaffPosition(excelBean.getStaffPosition());
            }
        }
        String commencement = excelBean.getCommencement();
        if (StringUtil.isNotBlank(commencement)){
            payRecordDetail.setCommencement(DateUtil.parse(commencement, DateUtil.PATTERN_MONTH));
        }
        String duration = excelBean.getDuration();
        if (StringUtil.isNotBlank(duration)){
            String[] split = duration.split(":");
            if (split.length == 2){
                payRecordDetail.setDurationStart(DateUtil.parse(split[0], DateUtil.PATTERN_MONTH));
                payRecordDetail.setDurationEnd(DateUtil.parse(split[1], DateUtil.PATTERN_MONTH));
            }
        }
        String corporatePayScale = excelBean.getCorporatePayScale();
        if (StringUtil.isNotBlank(corporatePayScale)){
            payRecordDetail.setCorporatePayScale(new BigDecimal(corporatePayScale));
        }
        String annualPayCoefficient = excelBean.getAnnualPayCoefficient();
        if (StringUtil.isNotBlank(annualPayCoefficient)){
            payRecordDetail.setAnnualPayCoefficient(new BigDecimal(annualPayCoefficient));
        }
        String excellentAward = excelBean.getExcellentAward();
        if (StringUtil.isNotBlank(excellentAward)){
            payRecordDetail.setExcellentAward(new BigDecimal(excellentAward));
        }
        String lastAnnualAdvance = excelBean.getLastAnnualAdvance();
        if (StringUtil.isNotBlank(lastAnnualAdvance)){
            payRecordDetail.setLastAnnualAdvance(new BigDecimal(lastAnnualAdvance));
        }
        String annualLiquidation = excelBean.getAnnualLiquidation();
        if (StringUtil.isNotBlank(annualLiquidation)){
            payRecordDetail.setAnnualLiquidation(new BigDecimal(annualLiquidation));
        }
        String tenureIncentive = excelBean.getTenureIncentive();
        if (StringUtil.isNotBlank(tenureIncentive)){
            payRecordDetail.setTenureIncentive(new BigDecimal(tenureIncentive));
        }
        String termIncentiveCoefficient = excelBean.getTermIncentiveCoefficient();
        if (StringUtil.isNotBlank(termIncentiveCoefficient)){
            payRecordDetail.setTermIncentiveCoefficient(new BigDecimal(termIncentiveCoefficient));
        }
        String annualRelease = excelBean.getAnnualRelease();
        if (StringUtil.isNotBlank(annualRelease)){
            payRecordDetail.setAnnualRelease(new BigDecimal(annualRelease));
        }
        String releaseBalance = excelBean.getReleaseBalance();
        if (StringUtil.isNotBlank(releaseBalance)){
            payRecordDetail.setReleaseBalance(new BigDecimal(releaseBalance));
        }
        payRecordDetail.setOtherIncome(excelBean.getOtherIncome());
        return payRecordDetail;
    }

    @Override
    public void toExcel(LeadershipPayRecordVO leadershipPayRecordVO, HttpServletResponse response) throws Exception {
        List<LeadershipPayRecordDetail> leadershipPayRecordDetails = leadershipPayRecordVO.getLeadershipPayRecordDetails();
        if (CollectionUtil.isNotEmpty(leadershipPayRecordDetails)){
            List<BigDecimal> annualPayCoefficients = leadershipPayRecordDetails.stream().map(LeadershipPayRecordDetail::getAnnualPayCoefficient).filter(Objects::nonNull).collect(Collectors.toList());
            leadershipPayRecordVO.setAnnualPayAverage(getAverage(annualPayCoefficients));

            List<BigDecimal> annualTimeCoefficients = leadershipPayRecordDetails.stream().map(LeadershipPayRecordDetail::getAnnualTimeCoefficient).filter(Objects::nonNull).collect(Collectors.toList());
            leadershipPayRecordVO.setAnnualTimeAverage(getAverage(annualTimeCoefficients));

            List<BigDecimal> termIncentiveCoefficients = leadershipPayRecordDetails.stream().map(LeadershipPayRecordDetail::getTermIncentiveCoefficient).filter(Objects::nonNull).collect(Collectors.toList());
            leadershipPayRecordVO.setTermIncentiveAverage(getAverage(termIncentiveCoefficients));

            List<BigDecimal> termTimeCoefficients = leadershipPayRecordDetails.stream().map(LeadershipPayRecordDetail::getTermTimeCoefficient).filter(Objects::nonNull).collect(Collectors.toList());
            leadershipPayRecordVO.setTermTimeAverage(getAverage(termTimeCoefficients));
            leadershipPayRecordDetails.forEach( detail ->{
                detail.setDuration(DateUtil.format(detail.getDurationStart(),DateUtil.PATTERN_MONTH) + ":" + DateUtil.format(detail.getDurationEnd(),DateUtil.PATTERN_MONTH));
                Optional.ofNullable(detail.getCommencement()).ifPresent(m -> detail.setCommencementStr(DateUtil.format(m, DateUtil.PATTERN_DATE)));
                //发放比例
                Optional.ofNullable(detail.getLastDistributionRatio()).ifPresent(m -> detail.setLastDistributionRatio(m.divide(new BigDecimal(100),4,RoundingMode.HALF_UP)));
                Optional.ofNullable(detail.getDistributionRatio()).ifPresent(m -> detail.setDistributionRatio(m.divide(new BigDecimal(100),4,RoundingMode.HALF_UP)));
            });
        }
        if (StringUtil.isNotBlank(leadershipPayRecordVO.getFillingYear())){
            String lastYear = DateUtil.format(DateUtil.minusYears(DateUtil.parse(leadershipPayRecordVO.getFillingYear(), DateUtil.PATTERN_YEAR), 1) , DateUtil.PATTERN_YEAR);
            leadershipPayRecordVO.setLastYear(lastYear);
        }
        Optional.ofNullable(leadershipPayRecordVO.getFillingTime()).ifPresent(m -> leadershipPayRecordVO.setFillingTimeStr(DateUtil.format(m, DateUtil.PATTERN_DATE)));

        String separator = File.separator;
        String exlPath = separator + "exceldemo" + separator + "pf" + separator + "leadership.xlsx";
        String fileName = "领导薪酬发放表.xls";
        InputStream inputStream = this.getClass().getResourceAsStream(exlPath);
        // 设置响应头和客户端保存文件名
        response.setCharacterEncoding("utf-8");
        // 设定输出文件头
        response.setHeader("Content-disposition", "attachment; filename="
                + new String(fileName.getBytes("GB2312"), "ISO8859-1"));
        // 定义输出类型
        response.setContentType("application/msexcel");
        // 取得输出流
        OutputStream outputStream = response.getOutputStream();
        response.reset();// 清空输出流
        ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(inputStream).build();
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        // 表一
        WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
        excelWriter.fill(new FillWrapper("d", leadershipPayRecordDetails), fillConfig, writeSheet);
        excelWriter.fill(leadershipPayRecordVO, writeSheet);
        excelWriter.finish();
        outputStream.close();
    }

    /**
     * @Description: //TODO 计算平均数
     * @Author: Take-off
     * @Date: 4:57 PM 2023/3/28
     * @Param: [list]
     * @return: java.math.BigDecimal
     **/
    private BigDecimal getAverage(List<BigDecimal> list){
        if (CollectionUtil.isNotEmpty(list)){
            BigDecimal sum = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
            return sum.divide(new BigDecimal(list.size()), 2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO;
    }

    @Override
    public String saveLeadershipRecord(String data) {
        YthResult ythResult = new YthResult();
        List<String> successIds = new ArrayList<>();
        List<String> failIds = new ArrayList<>();
        List<String> failReasons = new ArrayList<>();

        List<LeadershipPayRecord> dataList = JSON.parseArray(data, LeadershipPayRecord.class);
        if (CollectionUtil.isNotEmpty(dataList)) {
            Map<String, String> orgSourceMap = orgService.getSourceId();
            Map<String, String> userSourceMap = userService.getSourceId();
            List<StaffFiles> staffSources = staffFilesService.list(Wrappers.<StaffFiles>lambdaQuery().eq(StaffFiles::getDataSource, YthConstant.DATA_NINGBO));

            //根据datasourceIds 查询出所有的数据
            List<LeadershipPayRecord> list = list(new LambdaQueryWrapper<LeadershipPayRecord>().in(LeadershipPayRecord::getDataSourceId, dataList.stream().map(LeadershipPayRecord::getDataSourceId).toArray()).eq(LeadershipPayRecord::getStatus, UNREVIEWED));
            if (CollectionUtil.isNotEmpty(list)) {
                //删除子集
                List<Long> ids = list.stream().map(LeadershipPayRecord::getId).collect(Collectors.toList());
                payRecordDetailService.deleteByParentId(ids);
                payRecordDeclareService.deleteByParentId(ids);
            }
            for (LeadershipPayRecord entity:dataList){
                transfer(entity,orgSourceMap,userSourceMap,staffSources);
                //id重复略过
                if (CollectionUtil.isNotEmpty(list)){
                    List<String> olIds = list.stream().map(LeadershipPayRecord::getDataSourceId).collect(Collectors.toList());
                    String dataSourceId = entity.getDataSourceId();
                    //判断数据库中是否有数据
                    if (olIds.contains(dataSourceId)){
                        for (LeadershipPayRecord oldEntity:list){
                            if (dataSourceId.equals(oldEntity.getDataSourceId())){
                                //判断status是否为0，如果是0，就更新，不是0，就不更新
                                if (CheckStatus.checkCode(oldEntity.getStatus())){
                                    successIds.add(dataSourceId);
                                    entity.setId(oldEntity.getId());
                                    entity.setDataSource(YthConstant.DATA_NINGBO);
                                    submit(entity);
                                    list.remove(oldEntity);
                                    break;
                                }else {
                                    failIds.add(dataSourceId);
                                    failReasons.add("dataSourceId:"+dataSourceId+"数据已提交且已经在流程中，无法更新");
                                    break;
                                }
                            }
                        }
                    }else {
                        //如果数据库中没有数据，就新增
                        entity.setDataSource(YthConstant.DATA_NINGBO);
                        submit(entity);
                        successIds.add(entity.getDataSourceId());
                    }
                }else {
                    //如果数据库中没有数据，就新增
                    entity.setDataSource(YthConstant.DATA_NINGBO);
                    submit(entity);
                    successIds.add(entity.getDataSourceId());
                }
            }
        }else {
            failReasons.add("数据为空");
        }
        ythResult.setSuccessIds(successIds);
        ythResult.setFailIds(failIds);
        ythResult.setFailReason(StringUtils.join(failReasons, ";"));
        //ythResult转换成json字符串
        return JSON.toJSONString(ythResult);
    }

    private void transfer(LeadershipPayRecord leadershipPayRecord, Map<String, String> orgSourceMap,Map<String, String> userSourceMap
    ,List<StaffFiles> staffSources){
        Optional.ofNullable(leadershipPayRecord.getFillingUnitId()).ifPresent(m ->
                {
                    String orgId = orgSourceMap.get(m);
                    leadershipPayRecord.setFillingUnitId(orgId);
                    leadershipPayRecord.setCreateCompanyId(orgId);
                }
        );
        Optional.ofNullable(leadershipPayRecord.getFillingUser()).ifPresent(m ->
                {
                    String userId = userSourceMap.get(m);
                    leadershipPayRecord.setFillingUser(userId);
                    leadershipPayRecord.setCreateUser(userId);
                }
        );
        List<LeadershipPayRecordDetail> recordDetails = leadershipPayRecord.getLeadershipPayRecordDetails();
        if (CollectionUtil.isNotEmpty(recordDetails)){
            recordDetails.forEach(record ->{
                staffSources.stream().filter(m -> Optional.ofNullable(m.getDataSourceId()).isPresent() && record.getStaffDataId().equals(m.getDataSourceId())).findFirst().ifPresent(staff ->{
                    record.setStaffId(staff.getId());
                });
            });
        }
    }
}
